package connect

import (
	"encoding/json"
	"fmt"
	"ghw2/client/config"
	"net"
	"time"
)

type response struct {
	Services []string `json:"services"`
	Msg      string   `json:"msg"`
}

var ServiceAddressMapper map[string]*[]string = make(map[string]*[]string, 5)

var conn net.Conn

func Close() {
	conn.Close()
}

func ConnectNameSrvInit() error {
	var err error
	var n int
	buffer := make([]byte, 1023)
	if conn, err = net.Dial("tcp", config.ClientConfig.Namesrv); err != nil {
		fmt.Println(err)
		return err
	}
	_, err = conn.Write([]byte("client"))
	if err != nil {
		fmt.Println(err)
		conn.Close()
		return err
	}

	n, err = conn.Read(buffer)
	if err != nil {
		fmt.Println(err)
		conn.Close()
		return err
	}

	fmt.Println(string(buffer[:n]))
	return err
}

func GetAddressByService(serviceName string) (*[]string, error) {
	if v, ok := ServiceAddressMapper[serviceName]; ok {
		fmt.Printf("服务 %s 的路由信息%+v\n", serviceName, v)
		return v, nil
	}
	var err error
	var n int
	buffer := make([]byte, 2043)
	_, err = conn.Write([]byte(serviceName))
	if err != nil {
		fmt.Println(err)
		Close()
		return nil, err
	}
	n, err = conn.Read(buffer)
	if err != nil {
		Close()
		return nil, err
	}

	var res response
	json.Unmarshal(buffer[:n], &res)
	fmt.Println("Receive address ", res.Services, n, "which provide service ", serviceName, "\n")
	ServiceAddressMapper[serviceName] = &(res.Services)

	go updateServicesAddressMapper(serviceName)
	fmt.Printf("服务 %s 的路由信息%+v\n", serviceName, res)
	return &res.Services, err
}

// 当namesrv不可达时需要通知namesrv退出，这里应该时整个进程的结束，而我只把协程的结束给搞出来了
func updateServicesAddressMapper(serviceName string) {
	var err error
	var n int

	buffer := make([]byte, 2043)
	ticker := time.NewTicker(time.Second * 16)
	for range ticker.C {
		_, err = conn.Write([]byte(serviceName))
		if err != nil {
			fmt.Println(err)
			Close()
			return
		}
		n, err = conn.Read(buffer)
		if err != nil {
			Close()
			return
		}
		var res response
		json.Unmarshal(buffer[:n], &res)
		ServiceAddressMapper[serviceName] = &(res.Services)
	}
}
